﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Icoders.MarketTracker.Core.MasterData;
using Icoders.MarketTracker.Core.Repository.MasterDataRepositories;
using Icoders.MarketTracker.Web.Lib.MasterDataDTO;

namespace Icoders.MarketTracker.Web.Lib.Response.Services.Impl
{
   public class ClientMasterDataTrackerRepository : IClientMasterDataTrackerRepository
   {
       private ICountryRepository _countryRepository;
       private ICityRepository _cityRepository;
       private IAreaRepository _areaRepository;
       private IZoneRepository _zoneRepository;
       private IProductRepository _productRepository;
       private IPointOfPurchaseRepository _pointOfPurchaseRepository;
       private IPointOfPurchaseTypeRepository _pointOfPurchaseTypeRepository;
       private IClientRepository _clientRepository;
       private IReasonRepository _reasonRepository;
       private IUserRepository _userRepository;
       private IApplicationRepository _applicationRepository;
       private IFrsAssignRepository _frsAssignRepository;

       public ClientMasterDataTrackerRepository(ICountryRepository countryRepository, ICityRepository cityRepository, IAreaRepository areaRepository, IZoneRepository zoneRepository, IProductRepository productRepository, IPointOfPurchaseRepository pointOfPurchaseRepository, IPointOfPurchaseTypeRepository pointOfPurchaseTypeRepository, IClientRepository clientRepository, IReasonRepository reasonRepository, IUserRepository userRepository, IApplicationRepository applicationRepository, IFrsAssignRepository frsAssignRepository)
       {
           _countryRepository = countryRepository;
           _cityRepository = cityRepository;
           _areaRepository = areaRepository;
           _zoneRepository = zoneRepository;
           _productRepository = productRepository;
           _pointOfPurchaseRepository = pointOfPurchaseRepository;
           _pointOfPurchaseTypeRepository = pointOfPurchaseTypeRepository;
           _clientRepository = clientRepository;
           _reasonRepository = reasonRepository;
           _userRepository = userRepository;
           _applicationRepository = applicationRepository;
           _frsAssignRepository = frsAssignRepository;
       }

       public MasterDataEnvelope GetMasterDataEnvelope(int applicationId, int entityName)
       {
           foreach (SyncMasterDataCollective masterdata in Enum.GetValues(typeof(SyncMasterDataCollective)))//change to linq l8r
           {
               if (((int)masterdata) == entityName)
               {
                   return getEnvelope(applicationId, masterdata, null);
               }
           }
           throw new Exception("EntityName do not exist");
       }

       private MasterDataEnvelope getEnvelope(int applicationId, SyncMasterDataCollective masterdata, DateTime? dateChose)
       {
           DateTime dateSince = DateTime.Now.AddYears(-40);
           MasterDataEnvelope envelope = null;
           envelope = BuildEnvelope(applicationId, masterdata, dateSince, envelope);
           return envelope;
       }

       private MasterDataEnvelope BuildEnvelope(int applicationId, SyncMasterDataCollective masterdata, DateTime dateSince, MasterDataEnvelope envelope)
       {
           int userid = 0;
           MApplication app = _applicationRepository.GetById(applicationId);
           FrsAssign assign=null;
           if(app!=null)
           {
               userid = app.UserId;
               assign = _frsAssignRepository.GetByUser(userid);
           }
           switch (masterdata)
           {
               case SyncMasterDataCollective.Country:
                   if (_countryRepository.GetItemUpdatedSinceDateTime(dateSince))
                   {
                       var entity = _countryRepository.GetAll();
                       envelope = new MasterDataEnvelope
                                      {
                                          masterDataName = masterdata.ToString(),
                                          masterData = entity.Select(n => n as MasterEntityBase).ToList()
                                      };
                   }
                   break;
               case SyncMasterDataCollective.City:
                   if (_cityRepository.GetItemUpdatedSinceDateTime(dateSince))
                   {
                       var entity = _cityRepository.GetAll();
                       envelope = new MasterDataEnvelope
                       {
                           masterDataName = masterdata.ToString(),
                           masterData = entity.Select(n => n as MasterEntityBase).ToList()
                       };
                   }
                   break;
               case SyncMasterDataCollective.Area:
                   if (_areaRepository.GetItemUpdatedSinceDateTime(dateSince))
                   {
                       
                       var entity = new List<Area>();
                       if (assign != null)
                       {
                            entity = _areaRepository.GetAll().Where(s=>s.Id==assign.AreaId).ToList();
                       }
                       envelope = new MasterDataEnvelope
                       {
                           masterDataName = masterdata.ToString(),
                           masterData = entity.Select(n => n as MasterEntityBase).ToList()
                       };
                   }
                   break;
               case SyncMasterDataCollective.Zone:
                   if (_zoneRepository.GetItemUpdatedSinceDateTime(dateSince))
                   {
                       
                       var entity = new List<Zone>();
                       if (assign != null)
                       {
                           List<int> ids = _frsAssignRepository.GetZoneAssigned(assign.UserId);
                           entity = _zoneRepository.GetAll().Where(s => ids.Contains(s.Id) ).ToList();
                       }
                       envelope = new MasterDataEnvelope
                       {
                           masterDataName = masterdata.ToString(),
                           masterData = entity.Select(n => n as MasterEntityBase).ToList()
                       };
                   }
                   break;
               case SyncMasterDataCollective.PointOfPurchase:
                   if (_pointOfPurchaseRepository.GetItemUpdatedSinceDateTime(dateSince))
                   {
                      ;
                       var entity = new List<PointOfPurchase>();
                       if(assign!=null)
                       {
                           List<int> ids = _frsAssignRepository.GetZoneAssigned(assign.UserId);
                            entity = _pointOfPurchaseRepository.GetAll().Where(s=>ids.Contains(s.ZoneId)).ToList();
                       }
                      
                       envelope = new MasterDataEnvelope
                       {
                           masterDataName = masterdata.ToString(),
                           masterData = entity.Select(n => n as MasterEntityBase).ToList()
                       };
                   }
                   break;
               case SyncMasterDataCollective.PointOfPurchaseType:
                   if (_pointOfPurchaseTypeRepository.GetItemUpdatedSinceDateTime(dateSince))
                   {
                       var entity = _pointOfPurchaseTypeRepository.GetAll();
                       envelope = new MasterDataEnvelope
                       {
                           masterDataName = masterdata.ToString(),
                           masterData = entity.Select(n => n as MasterEntityBase).ToList()
                       };
                   }
                   break;
               case SyncMasterDataCollective.Client:
                   if (_clientRepository.GetItemUpdatedSinceDateTime(dateSince))
                   {
                       var entity = new List<Client>();// _clientRepository.GetAll();
                       if (assign != null)
                       {
                           entity = _clientRepository.GetAll().Where(s=>s.Id==assign.ClientId).ToList();
                       }
                       envelope = new MasterDataEnvelope
                       {
                           masterDataName = masterdata.ToString(),
                           masterData = entity.Select(n => n as MasterEntityBase).ToList()
                       };
                   }
                   break;
               case SyncMasterDataCollective.Product:
                   if (_productRepository.GetItemUpdatedSinceDateTime(dateSince))
                   {
                       var entity = new List<Product>();// _productRepository.GetByClient();
                       if (assign != null)
                       {
                           entity = _productRepository.GetByClient(assign.ClientId);
                       }
                       envelope = new MasterDataEnvelope
                       {
                           masterDataName = masterdata.ToString(),
                           masterData = entity.Select(n => n as MasterEntityBase).ToList()
                       };
                   }
                   break;
               case SyncMasterDataCollective.User:
                   if (_userRepository.GetItemUpdatedSinceDateTime(dateSince))
                   {
                       var entity = _userRepository.GetAll().Where(s=>s.Id==userid);
                       envelope = new MasterDataEnvelope
                       {
                           masterDataName = masterdata.ToString(),
                           masterData = entity.Select(n => n as MasterEntityBase).ToList()
                       };
                   }
                   break;
               case SyncMasterDataCollective.Reason:
                   if (_reasonRepository.GetItemUpdatedSinceDateTime(dateSince))
                   {
                       var entity = _reasonRepository.GetAll();
                       envelope = new MasterDataEnvelope
                       {
                           masterDataName = masterdata.ToString(),
                           masterData = entity.Select(n => n as MasterEntityBase).ToList()
                       };
                   }
                   break;
               default:
                   throw new Exception("Failed to map to DTO " + masterdata.ToString());
           }
           return envelope;

          
       }
    }
}
